#include "logger.h"
#include "utils.h"
#include <QDir>
#include <QFile>
#include <QFileInfo>
#include <QDateTime>
#include <QDate>
#include <QThread>
#include <QDebug>
#include <QJsonDocument>

/*
    创建一个日志对象，并将其打开，并自动设置其部分参数。
    如果创建并打开成功，则返回该对象的指针，否则返回NULL。

    通过本接口创建的日志对象，默认参数如下：

    日志头：appName+className+version
    日志名：appName+className+".log"
    日志存储路径：可执行程序所在目录的上一级/log目录
    日志备份路径：可执行程序所在目录的上一级/log目录
    日志等级：Debug
*/
Logger *Logger::createLogger(QObject *parent,const QString &moduleName,Logger::LogLevel level,bool enable)
{

    Logger* logger = new Logger(parent);
    logger->m_logWorker->setFileDir("./log");
    logger->m_logWorker->setFileName(moduleName);
    logger->m_logWorker->setHeader("");
    logger->m_logWorker->setBackupDir("./log");
    logger->setLogLevel(level);    
    logger->setEnable(enable);
    if(enable){
        logger->open();
    }else{
        logger->backup();
    }
    return logger;
}

/*
    构造函数。初始化对象参数。
*/
Logger::Logger( QObject *parent):QObject(parent)
{
    m_thread = new QThread(this);
    m_logWorker= new LogWorker();
    m_level= Logger::Debug;
    m_enable=true;

    connect(this,&Logger::sigOpen,m_logWorker,&LogWorker::open,Qt::QueuedConnection);
    connect(this,&Logger::sigWrite,m_logWorker,&LogWorker::write,Qt::QueuedConnection);
}

/*
    析构函数。关闭文件
*/
Logger::~Logger()
{
   close();
}

/*
    打开日志
*/
void Logger::open()
{
    m_logWorker->moveToThread(m_thread);
    m_thread->start();

    emit sigOpen();
}

/*
    关闭日志
*/
void Logger::close()
{
    m_thread->quit();
    m_thread->wait();
    m_logWorker->close();
    delete m_logWorker;
}

void Logger::backup()
{
    m_logWorker->backup();
}


/*
    返回当前可输出的日志等级
*/
Logger::LogLevel Logger::logLevel()
{
    return m_level;
}

/*
    设置当前可输出的日志等级
*/
void Logger::setLogLevel(Logger::LogLevel level)
{
    m_level = level;
}

/*
    返回日志是否被禁用
*/
bool Logger::enable()
{
    return m_enable;
}

/*
    设置是否禁用日志输出，如果日志被禁用则不会输出日志到文件中。
*/
void Logger::setEnable(bool enable)
{
    m_enable=enable;
}

/*
    输出Debug级别的日志。Debug级别一般用于输出调试信息。

    注意：如果logLevel()的级别高于当前Debug，则不会输出日志。
*/
void Logger::debug(const QString &text)
{
    if(m_level  <= Logger::LogLevel::Debug){
        this->write("Debug",text);
    }
}

/*
    输出Info级别的日志。Info级别一般用于输出提示性信息。

    注意：如果logLevel()的级别高于当前Info，则不会输出日志。
*/
void Logger::info(const QString &text)
{
    if(m_level  <= Logger::LogLevel::Info){
        this->write("Info",text);
    }
}

/*
    输出Warn级别的日志。Warn级别一般用于输出警告性信息。

    注意：如果logLevel()的级别高于当前Warn，则不会输出日志。
*/
void Logger::warn(const QString &text)
{
    if(m_level  <= Logger::LogLevel::Warn){
        this->write("Warn",text);
    }
}

/*
    输出Error级别的日志。Erro级别一般用于输出错误信息。

    注意：如果logLevel()的级别高于当前Error，则不会输出日志。
*/
void Logger::error(const QString &text)
{
    if(m_level  <= Logger::LogLevel::Error){
        this->write("Error",text);
    }
}

/*
    输入level级别的日志。

    注意：如果logLevel()的级别高于level，则不会输出日志。
*/
void Logger::log(Logger::LogLevel level, const QString &text)
{
    if(m_level <= level){
        QString strLevel = Utils::enumToString<Logger::LogLevel>(level);
        this->write(strLevel,text);
    }
}

/*
    写日志文件。写入的日志格式为：

    [日期] [日志等级] 日志信息

    level：日志等级。
    text：需要写入文件的日志信息。
*/
void Logger::write(const QString &level, const QString &text)
{     
    if(m_enable){
        QDateTime curDateTime = QDateTime::currentDateTime();
        QString curDateTimeStr = curDateTime.toString("yyyy-MM-dd HH:mm:ss.zzz");
        QString log = QString("\n[%1] [%2] %3")
                .arg(curDateTimeStr)
                .arg(level)
                .arg(text);

        emit this->sigWrite(log);
    }
}
